package com.suntop.carousel.qlmediaplay.video.player;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;

import com.pili.pldroid.player.PLMediaPlayer;
import com.suntop.carousel.qlmediaplay.field.Field_State;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Target;
import java.util.Map;

import androidx.annotation.RequiresApi;

@RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
public class AndroidMediaPlayer implements IVideoPlayer, MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener,
        MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnPreparedListener,
        MediaPlayer.OnVideoSizeChangedListener {
    private MediaPlayer mMediaPlayer;
    private float lefVolme, rightVolme;
    private IVideoPlayerEventListener mListener;
    private AssetFileDescriptor fileDescriptor;
    private int current = Field_State.IDLE;
    private Map<String, String> mHeader;
    private String playURl = "";
    private String playName = "";
    private String Tag = "";
    private boolean isLoop;
    private int cacheProgress = 0;
    private boolean mIsPrepared;
    private boolean isRetBack=false;
    private Context applicationContext;

    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    public AndroidMediaPlayer(Context context) {
        initPlayer(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    @Override
    public void initPlayer(Context context) {
        applicationContext = context.getApplicationContext();
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer=null;
        }
        mMediaPlayer=new MediaPlayer();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setOnBufferingUpdateListener(this);
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnVideoSizeChangedListener(this);
        current = Field_State.IDLE;

    }

    @Override
    public IVideoPlayer setPlayUrl(String url) {
        setPlayUrl(url, null);
        return this;
    }

    @Override
    public IVideoPlayer setPlayUrl(String url, Map<String, String> header) {
        this.playURl = url;
        fileDescriptor = null;
        return this;
    }



    @Override
    public IVideoPlayer setScaleType(int type) {
        return this;
    }

    @Override
    public IVideoPlayer setAssetFileDescriptor(AssetFileDescriptor fd) {
        this.playURl = "";
        fileDescriptor = fd;
        return this;
    }

    @Override
    public IVideoPlayer setVideoTag(String tag) {
        this.Tag = tag;
        return this;
    }

    @Override
    public IVideoPlayer setLoop(boolean isLoop) {
        this.isLoop = isLoop;
        if (mMediaPlayer != null) {
            mMediaPlayer.setLooping(isLoop);
        }
        return this;
    }

    @Override
    public IVideoPlayer setVolume(float left, float right) {
        this.lefVolme = (int) left;
        this.rightVolme = (int) right;
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(lefVolme, rightVolme);
        }
        return this;
    }

    @Override
    public IVideoPlayer setPlaySpeed(float speed) {
        if (mMediaPlayer != null)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(speed));
            }
        return this;
    }

    @Override
    public IVideoPlayer setIVideoPlayerEventListener(IVideoPlayerEventListener eventListener) {
        mListener = eventListener;
        return this;
    }

    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public IVideoPlayer setSurface(Surface surface) {
        if (mMediaPlayer != null) {
            mMediaPlayer.setSurface(surface);
        }
        return this;
    }

    @Override
    public IVideoPlayer setDisplay(SurfaceHolder holder) {
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(holder);
        }
        return this;
    }

    @Override
    public IVideoPlayer seekTo(long time) {
        if (isOnPlaying()) {
            mMediaPlayer.seekTo((int) time);
        }
        return this;
    }

    @Override
    public boolean isOnPlaying() {
        return mMediaPlayer != null && (current == Field_State.PAUSED
                || current == Field_State.PREPARED
                || current == Field_State.PLAYING
                ||mMediaPlayer.isPlaying());
    }

    @Override
    public boolean isNeedRest() {
        return mMediaPlayer == null || current == Field_State.ERROR
                || current == Field_State.IDLE || current == Field_State.INTERRUPT
                ||current==Field_State.COMPLETED
                || current == Field_State.DESTROYED;
    }

    @Override
    public boolean isReBack() {
        return isRetBack;
    }

    @Override
    public boolean mIsPrepared() {
        return mIsPrepared;
    }

    @Override
    public String takePlayUrl() {
        return playName;
    }

    @Override
    public String takePlayTag() {
        return Tag;
    }

    @Override
    public int getPlayState() {
        return current;
    }

    @Override
    public long getCurrentPosition() {
        return mMediaPlayer == null ? 0 : mMediaPlayer.getCurrentPosition();
    }

    @Override
    public long getDuration() {
        return mMediaPlayer == null ? 0 : mMediaPlayer.getDuration();
    }

    @Override
    public int getBufferedPercentage() {
        return cacheProgress;
    }

    @Override
    public float getSpeed() {
        if (mMediaPlayer == null)
            return 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return mMediaPlayer.getPlaybackParams().getSpeed();
        }
        return 0;
    }

    @Override
    public long getTcpSpeed() {
        return 0;
    }

    @Override
    public int getVideoWidth() {
        return mMediaPlayer == null ? 0 : mMediaPlayer.getVideoWidth();
    }

    @Override
    public int getVideoHeight() {
        return mMediaPlayer == null ? 0 : mMediaPlayer.getVideoHeight();
    }

    @Override
    public void setIsPrepared(boolean isPrepared) {
        this.mIsPrepared = isPrepared;
    }

    @Override
    public void setIsReBack(boolean isReBack) {
        this.isRetBack=isReBack;
    }

    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void prepareAsync() {
        if (mMediaPlayer == null) {
            return;
        }
        mMediaPlayer.reset();
        try {
            cacheProgress = 0;
            if (fileDescriptor != null) {
                mMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(),
                        fileDescriptor.getLength());
                playName = fileDescriptor.getFileDescriptor().toString();
            } else if (!TextUtils.isEmpty(playURl)) {
                playName=playURl;
                if (mHeader != null)
                    mMediaPlayer.setDataSource(applicationContext,Uri.fromFile(new File(playURl)), mHeader);
                else
                    mMediaPlayer.setDataSource(playURl);
            }
            current = Field_State.PREPARING;
            mMediaPlayer.setVolume(0,0);
            mMediaPlayer.prepareAsync();
        } catch (IOException exception) {
            current = Field_State.ERROR;
            reset();
            Log.e("播放器错误", exception + "");
            if (mListener != null) {
                mListener.onError(Tag, exception + "");
            }
            exception.printStackTrace();
        }
    }

    @Override
    public void start() {
        if (isOnPlaying() || current == Field_State.COMPLETED) {
            mMediaPlayer.start();
        }
    }

    @Override
    public void pause() {
        if (mMediaPlayer != null) {
            current = Field_State.PAUSED;
            mMediaPlayer.pause();
        }
    }

    @Override
    public void stop() {
        if (isOnPlaying()) {
            current = Field_State.INTERRUPT;
            mMediaPlayer.stop();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void reset() {
        stop();
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.setDisplay(null);
            mMediaPlayer.setSurface(null);
//            mMediaPlayer.setVolume(lefVolme, rightVolme);
        }
        current = Field_State.IDLE;
    }

    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void release() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setOnErrorListener(null);
            mMediaPlayer.setOnCompletionListener(null);
            mMediaPlayer.setOnInfoListener(null);
            mMediaPlayer.setOnBufferingUpdateListener(null);
            mMediaPlayer.setOnPreparedListener(null);
            mMediaPlayer.setOnVideoSizeChangedListener(null);
            mMediaPlayer.stop();
            mMediaPlayer.setSurface(null);
            mMediaPlayer.setDisplay(null);
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        current = Field_State.DESTROYED;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        cacheProgress = percent;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        current = Field_State.COMPLETED;
        if (!isReBack()){
            stop();
        }
        if (mListener != null) {
            mListener.onCompletion(Tag);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        current = Field_State.ERROR;
        if (mListener != null) {
            mListener.onError(Tag, "错误 what=" + what + " extra=" + extra);
        }
        reset();
        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
            current = Field_State.PLAYING;
        }
        if (mListener != null) {
            mListener.onInfo(Tag, what, extra);
        }
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        current = Field_State.PREPARED;
        Log.e("播放器 onPrepared", mIsPrepared + "");
        if (mListener != null) {
            mListener.onPrepared(Tag);
        }
        mp.setVolume(lefVolme,rightVolme);
        if (mIsPrepared()) {
            mp.start();
        }
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        int videoWidth = mp.getVideoWidth();
        int videoHeight = mp.getVideoHeight();
        if (videoWidth != 0 && videoHeight != 0 && mListener != null) {
            mListener.onVideoSizeChanged(Tag, videoWidth, videoHeight);
        }
    }
}
